package com.fitc.imageprocessing;

import java.awt.Color;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;

import javax.imageio.ImageIO;

import ij.ImagePlus;
import ij.process.ColorProcessor;
import ij.process.ImageProcessor;
import ij.process.TypeConverter;

public class AverageColor {

	ImageProcessor _ip;
	ImagePlus inImage,outImage;
	public Color[] avgColors;
	public Color avgColor;
	static final int GRID = 3;
	
	
	public AverageColor(ImagePlus in) {
		this.inImage = in;
		this._ip = (ImageProcessor) inImage.getProcessor();
		
		TypeConverter tp = new TypeConverter(_ip, false);
		_ip = tp.convertToRGB();
		
		avgColor = genAverageColor(_ip);
		avgColors = genAvgColorGrid(_ip);
		Color c= new Color(0);
		
	}

	private static Color[] genAvgColorGrid(ImageProcessor ip) {
		Color[] colors = new Color[GRID*GRID];
		
		int gridWidth = ip.getWidth()/GRID;
		int gridHeight = ip.getHeight()/GRID;
		int i = 0;
		for (int x=0; x<ip.getWidth();x=x+gridWidth){
			for (int y=0; y<ip.getWidth();y=y+gridHeight){
				ImageProcessor np = ip.duplicate();
				np.setRoi(x, y, gridWidth, gridHeight);
				np = np.crop();
				colors[i] = (genAverageColor(np));
				i++;
			}
		}
		return colors;
	}
	
	public void saveAvgColorGridPng(){
		outImage = new ImagePlus();
		outImage.setImage(inImage);

		ImageProcessor op = outImage.getProcessor();
		
		int gridWidth = op.getWidth()/GRID;
		int gridHeight = op.getHeight()/GRID;
		int i = 0;
		for (int x=0; x<op.getWidth();x=x+gridWidth){
			for (int y=0; y<op.getWidth();y=y+gridHeight){
				op.setColor(avgColors[i]);
				Rectangle r = new Rectangle(x, y, gridWidth, gridHeight);
				op.setRoi(r);
				op.fill();
				
				i++;
			}
		}
		
		
		
		int[] pixels = (int[]) op.getPixels();
		BufferedImage bimg = new BufferedImage(op.getWidth(),
				op.getHeight(), BufferedImage.TYPE_INT_RGB);
		bimg.setRGB(0, 0, op.getWidth(), op.getHeight(), pixels,
				0, op.getWidth());

		try {
			File outputfile = new File("saved.png");
			ImageIO.write(bimg, "png", outputfile);
		} catch (IOException e) {

		}
	}

	public static Color genAverageColor(ImageProcessor ip) {
		ColorProcessor cp = (ColorProcessor) ip;
		int[] avgColor = { 0, 0, 0 };
		int pixNum = cp.getPixelCount();
		
		for (int x=0; x<cp.getWidth();x++){
			for (int y=0; y<cp.getWidth();y++){
				int pix = cp.get(x, y);
				avgColor[0] += (pix >> 16) & 0xFF;
				avgColor[1] += (pix >> 8) & 0xFF;
				avgColor[2] += pix & 0xFF;
			}
		}	

		avgColor[0] /= pixNum;
		avgColor[1] /= pixNum;
		avgColor[2] /= pixNum;
		
		return new Color (avgColor[0],avgColor[1],avgColor[2]);
	}
	
	public static float[] getAsHSB(Color c){
		return Color.RGBtoHSB(c.getRed(),c.getGreen(), c.getBlue(), null);
	}
	
	public static float[] RGBtoHSB(Color c){
		return RGBtoHSB(c.getRed(),c.getGreen(), c.getBlue());
	}
	
	public static float[] RGBtoHSB(int r,int g,int b){
		float hsb[] = new float[3];
		final float UNDEFINED = 0;
		float h,s,v;
		h = 0;
		float r_ = r/255.0f;
		float g_ = g/255.0f;
		float b_ = b/255.0f;
		float max = Math.max(Math.max(r_, g_), b_);
		float min = Math.min(Math.min(r_, g_), b_);
		v = max;
		//calc saturation
		if (max!=0){
			s = (max-min)/ (float)max;
		} else {
			s = 0;
		} 
		if (s==0){
			h= UNDEFINED;
		} else {
			float d = max - min;
			if (r_==max){
				h= (g_-b_)/d;
			} else if (g_==max){
				h= 2+(b_-r_)/d;
			}else if (b_==max){
				h= 4+(b_-g_)/d;
			}
			h=h*60;
			if (h<0) h=h+360;
		}
		hsb[0]= (h/360);
		hsb[1]= s;
		hsb[2]= v;
		
		return hsb;	
	}

}
